package com.echovin.esb.gateway.predicate;

import com.echovin.esb.gateway.oauth2.handler.OAuth2AccessDecisionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.util.function.Predicate;

import java.util.Collections;
import java.util.List;

/**
 * token校验断言
 */
@Component
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<TokenRoutePredicateFactory.Config> {
    private static final String DATETIME_KEY = "headerName";

    @Autowired
    OAuth2AccessDecisionManager manager;

    public TokenRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList(DATETIME_KEY);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            //判断header里有放token
            HttpHeaders headers = exchange.getRequest().getHeaders();
            String token = headers.getFirst(config.getHeaderName());
            return this.process(exchange, token);
        };
    }

    private boolean process(ServerWebExchange exchange, String token) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        HttpHeaders headers = request.getHeaders();
        String url = request.getURI().getPath();
        if (request.getHeaders().get("SOAPAction") != null && !request.getHeaders().get("SOAPAction").isEmpty()) {
            // 说明是webservice，对其动作进行权限校验
            List<String> list = request.getHeaders().get("SOAPAction");
            url = list.get(0);
        }
        // 判断当前操作是否在列表中，无权限则返回提示页面
        return manager.checkPermission(token, url, null);
    }

    public static class Config {
        /**
         * 传输token header key
         */
        private String headerName;

        public String getHeaderName() {
            return headerName;
        }

        public void setHeaderName(String headerName) {
            this.headerName = headerName;
        }
    }
}
